package org.example.lease.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.lease.mapper.RoomInfoMapper;
import org.example.lease.model.entities.*;
import org.example.lease.model.enums.ItemType;
import org.example.lease.service.*;
import org.example.lease.vo.attr.AttrValueVo;
import org.example.lease.vo.graph.GraphVo;
import org.example.lease.vo.room.RoomDetailVo;
import org.example.lease.vo.room.RoomItemVo;
import org.example.lease.vo.room.RoomQueryVo;
import org.example.lease.vo.room.RoomSubmitVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author 宋孟林
 * @description
 * @date: 2025/5/12 16:52
 */
@Service
@Slf4j
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo> implements RoomInfoService {
    @Resource
    private RoomInfoMapper roomInfoMapper;
    @Resource
    private GraphInfoService graphInfoService;
    @Resource
    private RoomAttrValueService roomAttrValueService;
    @Resource
    private RoomFacilityService roomFacilityService;
    @Resource
    private RoomLabelService roomLabelService;
    @Resource
    private RoomPaymentTypeService roomPaymentTypeService;
    @Resource
    private RoomLeaseTermService roomLeaseTermService;
    @Resource
    private ApartmentInfoService apartmentInfoService;

    /**
     * 保存或者更新房间的基本信息
     * 同时保存和房间有关的关联表信息，关联表如下
     * 图片-房间
     * 属性值-房间
     * 配套-房间
     * 标签-房间
     * 支付方式-房间
     * 可选租期-房间
     *
     * @param roomSubmitVo 房间提交VO
     */
    @Transactional
    @Override
    public void saveOrUpdateRoomSubmitVo(RoomSubmitVo roomSubmitVo) {
        Long roomId = roomSubmitVo.getId();
        RoomInfo roomInfo = roomInfoMapper.selectById(roomId);
        boolean isSave = roomInfo == null;
        //保存基本房间信息
        this.saveOrUpdate(roomSubmitVo);
        //如果是非保存那就是更新，更新先删除之前和房间关联的表的内容,再插入submitVo中包含的信息
        if (!isSave) {
            removeRoomAssociations(roomId);
        }
        //插入和房间相关的图片信息---使用stream api
        List<GraphVo> graphVoList = roomSubmitVo.getGraphVoList();
        if (!CollectionUtils.isEmpty(graphVoList)) {
            List<GraphInfo> graphInfoList = graphVoList.stream().map(graphVo -> {
                GraphInfo graphInfo = new GraphInfo();
                graphInfo.setItemId(roomId);
                graphInfo.setUrl(graphVo.getUrl());
                graphInfo.setItemType(ItemType.ROOM);
                graphInfo.setName(graphInfo.getName());
                return graphInfo;
            }).toList();//jdk16语法
            graphInfoService.saveBatch(graphInfoList);
        }
        //将房间和属性值关联的信息插入到中间表房间-属性值表----使用stream api来插入
        List<Long> attrValueIds = roomSubmitVo.getAttrValueIds();
        if (!CollectionUtils.isEmpty(attrValueIds)) {
            List<RoomAttrValue> roomAttrValueList = attrValueIds.stream().map(attrValueId ->
                    RoomAttrValue.builder().attrValueId(attrValueId).roomId(attrValueId).build()).toList();
            roomAttrValueService.saveBatch(roomAttrValueList);
        }
        //将房间和配套关联的信息插入到中间表房间-配套表----使用stream api来插入
        List<Long> facilityInfoIds = roomSubmitVo.getFacilityInfoIds();
        if (!CollectionUtils.isEmpty(facilityInfoIds)) {
            List<RoomFacility> roomFacilityList = facilityInfoIds.stream().map(facilityInfoId ->
                    RoomFacility.builder().facilityId(facilityInfoId).roomId(roomId).build()).toList();
            roomFacilityService.saveBatch(roomFacilityList);
        }
        //将房间和标签关联的信息插入到中间表房间-标签表----使用stream api来插入
        List<Long> labelInfoIds = roomSubmitVo.getLabelInfoIds();
        if (!CollectionUtils.isEmpty(labelInfoIds)) {
            List<RoomLabel> roomLabelList = labelInfoIds.stream().map(labelInfoId ->
                    RoomLabel.builder().labelId(labelInfoId).roomId(roomId).build()).toList();
            roomLabelService.saveBatch(roomLabelList);
        }
        //将房间和支付方式关联的信息插入到中间表房间-支付方式表----使用stream api来插入
        List<Long> paymentTypeIds = roomSubmitVo.getPaymentTypeIds();
        if (!CollectionUtils.isEmpty(paymentTypeIds)) {
            List<RoomPaymentType> roomPaymentTypeList = paymentTypeIds.stream().map(paymentTypeId ->
                    RoomPaymentType.builder().paymentTypeId(paymentTypeId).roomId(roomId).build()).toList();
            roomPaymentTypeService.saveBatch(roomPaymentTypeList);
        }
        //将房间和可选租期关联的信息插入到中间表房间-可选租期表----使用stream api来插入
        List<Long> leaseTermIds = roomSubmitVo.getLeaseTermIds();
        if (!CollectionUtils.isEmpty(leaseTermIds)) {
            List<RoomLeaseTerm> roomLeaseTermList = leaseTermIds.stream().map(leaseTermId ->
                    RoomLeaseTerm.builder().leaseTermId(leaseTermId).roomId(roomId).build()).toList();
            roomLeaseTermService.saveBatch(roomLeaseTermList);
        }
    }

    /**
     * 根据条件分页查询房间VO信息
     *
     * @param page        page
     * @param roomQueryVo vo
     * @return list---> roomItemVo
     */
    @Override
    public IPage<RoomItemVo> pageRoomItemVo(IPage<RoomItemVo> page, RoomQueryVo roomQueryVo) {
        IPage<RoomItemVo> roomItemVoIPage = roomInfoMapper.pageRoomItemVo(page, roomQueryVo);
        log.info("roomItemVos已经查出： {}", roomItemVoIPage);
        return roomItemVoIPage;
    }

    @Override
    public RoomDetailVo getRoomDetailVoByRoomId(Long id) {
        RoomDetailVo roomDetailVo = new RoomDetailVo();
        RoomInfo roomInfo = roomInfoMapper.selectById(id);
        if (roomInfo == null) {
            return null;
        }
        BeanUtils.copyProperties(roomInfo, roomDetailVo);
        //查询房间对应的公寓信息
        Long apartmentId = roomInfo.getApartmentId();
        ApartmentInfo apartmentInfo = apartmentInfoService.getById(apartmentId);
        roomDetailVo.setApartmentInfo(apartmentInfo);
        //查询房间对应的图片信息
        List<GraphInfo> graphInfoList = graphInfoService.list(Wrappers.lambdaQuery(GraphInfo.class)
                .eq(GraphInfo::getItemType, ItemType.ROOM).eq(GraphInfo::getItemId, id));
        List<GraphVo> graphVoList = graphInfoList.stream().map(graphInfo -> {
            GraphVo graphVo = new GraphVo();
            BeanUtils.copyProperties(graphInfo, graphVo);
            return graphVo;
        }).toList();
        roomDetailVo.setGraphVoList(graphVoList);
        //查询房间对应的属性值vo信息列表
        List<AttrValueVo> attrValueVos = roomInfoMapper.selectRoomAttrValueVoByRoomId(id);
        roomDetailVo.setAttrValueVoList(attrValueVos);
        //查询房间对应的配套信息列表
        List<FacilityInfo> facilityInfos = roomInfoMapper.selectRoomFacilityInfoByRoomId(id);
        roomDetailVo.setFacilityInfoList(facilityInfos);
        //查询房间对应的标签信息列表
        List<LabelInfo> labelInfos = roomInfoMapper.selectRoomLabelInfoByRoomId(id);
        roomDetailVo.setLabelInfoList(labelInfos);
        //查询房间对应的支付方式列表
        List<PaymentType> paymentTypes = roomInfoMapper.selectRoomPaymentTypeByRoomId(id);
        roomDetailVo.setPaymentTypeList(paymentTypes);
        //查询房间对应的可选租期列表
        List<LeaseTerm> leaseTerms = roomInfoMapper.selectLeaseTermByRoomId(id);
        roomDetailVo.setLeaseTermList(leaseTerms);
        log.info("roomDetailVo对象已经封装完毕：{}", roomDetailVo);
        return roomDetailVo;
    }

    /**
     * 根据id删除房间以及和房间关联的关联表信息
     *
     * @param id roomId
     */
    @Transactional
    @Override
    public void removeRoomById(Long id) {
        //删除基本的房间信息表
        int i = roomInfoMapper.deleteById(id);
        if (i > 0) {
            removeRoomAssociations(id);
        }
    }

    /**
     * 删除与房间相关的所有中间表记录
     *
     * @param roomId 房间ID
     */
    private void removeRoomAssociations(Long roomId) {
        // 删除图片和房间关联信息
        graphInfoService.remove(Wrappers.lambdaQuery(GraphInfo.class)
                .eq(GraphInfo::getItemType, ItemType.ROOM).eq(GraphInfo::getItemId, roomId));
        // 删除属性和房间关联信息
        roomAttrValueService.remove(Wrappers.lambdaQuery(RoomAttrValue.class)
                .eq(RoomAttrValue::getRoomId, roomId));
        // 删除房间和配套相关信息
        roomFacilityService.remove(Wrappers.lambdaQuery(RoomFacility.class)
                .eq(RoomFacility::getRoomId, roomId));
        // 删除房间相关标签信息
        roomLabelService.remove(Wrappers.lambdaQuery(RoomLabel.class)
                .eq(RoomLabel::getRoomId, roomId));
        // 删除房间相关支付方式信息
        roomPaymentTypeService.remove(Wrappers.lambdaQuery(RoomPaymentType.class)
                .eq(RoomPaymentType::getRoomId, roomId));
        // 删除房间相关租期信息
        roomLeaseTermService.remove(Wrappers.lambdaQuery(RoomLeaseTerm.class)
                .eq(RoomLeaseTerm::getRoomId, roomId));
        log.info("已删除房间 ID={} 相关的中间表记录", roomId);
    }

}




